﻿' Inherit custom: http://geekswithblogs.net/lbugnion/archive/2007/03/02/107747.aspx
' Design mode: http://blogs.msdn.com/jnak/archive/2006/10/07/Detecting-Design-Mode.aspx

Imports System.Collections.Generic
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Data
Imports System.Windows.Documents
Imports System.Windows.Input
Imports System.Windows.Media
Imports System.Windows.Media.Imaging
Imports System.Windows.Shapes
Imports WinForms = System.Windows.Forms
Imports Microsoft.Win32
Imports System.Reflection

''' <summary>
''' Interaction logic for ApplicationWindow.xaml
''' </summary>
Partial Public Class ApplicationWindow
    Inherits Window

    Private showHiddenMessage As Boolean = True
    Private m_hideOnClose As Boolean = True
    Private designMode As Boolean
    Private appName As String = "Application"
    Private _trayNotifyIcon As WinForms.NotifyIcon = New System.Windows.Forms.NotifyIcon()

    Public Sub New()
        ' Visual Studio creates an instance for the Designer window.  We don't want
        ' a tray icon from a Designer instance!
        designMode = System.ComponentModel.DesignerProperties.GetIsInDesignMode(Me)

        If Not designMode Then
            Dim cm As New WinForms.ContextMenu()

            ' Ugly manual menu creation
            Dim mi As WinForms.MenuItem = cm.MenuItems.Add("Show Settings")
            mi.DefaultItem = True
            AddHandler mi.Click, AddressOf ShowApp

            mi = cm.MenuItems.Add("-")

            mi = cm.MenuItems.Add("Start with Windows")
            mi.Name = "StartupCommand"
            AddHandler mi.Click, AddressOf ToggleWindowsStartup
            mi.Checked = GetWindowsStartupState()

            mi = cm.MenuItems.Add("Exit")
            AddHandler mi.Click, AddressOf Application.Current.Shutdown

            ' Initializes NotifyIcon for icon, men, and text
            _trayNotifyIcon.Icon = My.Resources.DefaultTrayIcon
            _trayNotifyIcon.ContextMenu = cm
            _trayNotifyIcon.Text = appName
            AddHandler _trayNotifyIcon.DoubleClick, AddressOf ShowApp

            _trayNotifyIcon.Visible = True

        End If
    End Sub

    Private Sub ShowApp()
        Me.Show()
        Me.WindowState = WindowState.Normal
    End Sub

    Private Sub ToggleWindowsStartup()

        Using hkcu As RegistryKey = Registry.CurrentUser

            Using runKey As RegistryKey = hkcu.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run", True)

                Dim appVal As Object = runKey.GetValue("UtilRunner")
                Dim mi As WinForms.MenuItem = TrayIconMenu.MenuItems("StartupCommand")

                If appVal Is Nothing Then
                    runKey.SetValue("UtilRunner", Assembly.GetEntryAssembly().Location)
                    mi.Checked = True
                Else
                    runKey.DeleteValue("UtilRunner")
                    mi.Checked = False
                End If
            End Using
        End Using
    End Sub

    Private Function GetWindowsStartupState() As Boolean

        Using hkcu As RegistryKey = Registry.CurrentUser

            Using runKey As RegistryKey = hkcu.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run", True)

                Dim runVal As Object = runKey.GetValue("UtilRunner")

                If runVal Is Nothing Then
                    Return False

                Else
                    Return True
                End If
            End Using
        End Using
    End Function

    ''' <summary>
    ''' Restores window when app is initialized
    ''' </summary>
    Private Sub ApplicationWindow_Initialized(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Initialized
        RestoreWindowState()
    End Sub

    ''' <summary>
    ''' Handles SizeChanged event for the window
    ''' </summary>
    Private Sub ApplicationWindow_SizeChanged(ByVal sender As Object, ByVal e As SizeChangedEventArgs) Handles Me.SizeChanged
        SaveWindowState()
    End Sub

    ''' <summary>
    ''' Handles SizeChanged event for the window
    ''' </summary>
    Private Sub ApplicationWindow_LocationChanged(ByVal sender As Object, ByVal e As EventArgs) Handles Me.LocationChanged
        SaveWindowState()
    End Sub

    ''' <summary>
    ''' Gets or sets a value that indicates whether the close button should send
    ''' the application to tray (true) or exit (false).
    ''' </summary>
    Public Property HideOnClose() As Boolean
        Get
            Return m_hideOnClose
        End Get
        Set(ByVal value As Boolean)
            m_hideOnClose = value
        End Set
    End Property

    ''' <summary>
    ''' Handles Closing event for the window and determines if the application should hide or close
    ''' </summary>
    Private Sub ApplicationWindow_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles Me.Closing
        If m_hideOnClose Then
            e.Cancel = True
            If showHiddenMessage Then
                AddHandler _trayNotifyIcon.Click, AddressOf HideHiddenMessage

                _trayNotifyIcon.ShowBalloonTip(10000, appName & " - " & "Minimized", appName & " has been minimized to the tray.  Click this message to hide this message in the future.", System.Windows.Forms.ToolTipIcon.Info)
            End If
            Me.WindowState = WindowState.Minimized
            Me.Hide()
        Else
            SaveWindowState()
        End If
    End Sub

    Private Sub HideHiddenMessage()
        showHiddenMessage = False
    End Sub

    ''' <summary>
    ''' Saves position and size information to application settings
    ''' </summary>
    Friend Sub SaveWindowState()
        If Me.WindowState = WindowState.Normal Then
            My.Settings.LastWindowPosition = New System.Drawing.Point(CInt(Me.Left), CInt(Me.Top))
            My.Settings.LastWindowSize = New System.Drawing.Size(CInt(Me.Width), CInt(Me.Height))
            My.Settings.Save()
        End If
    End Sub

    ''' <summary>
    ''' Reads Restores the window size/location from application settings
    ''' </summary>
    Friend Sub RestoreWindowState()
        Me.Show()
        Me.Left = My.Settings.LastWindowPosition.X
        Me.Top = My.Settings.LastWindowPosition.Y
        Me.Width = My.Settings.LastWindowSize.Width
        Me.Height = My.Settings.LastWindowSize.Height
        Me.Hide()
    End Sub

    ''' <summary>
    ''' Sets the name of the application.  Used by the window title and NotifyIcon
    ''' </summary>
    Public Property ApplicationName() As String
        Get
            Return appName
        End Get
        Set(ByVal value As String)
            appName = value
            Me.Title = value
            _trayNotifyIcon.Text = value
        End Set
    End Property

    ''' <summary>
    ''' Displays a status message using a NotifyIcon balloon tip
    ''' </summary>
    ''' <param name="title"></param>
    ''' <param name="msg"></param>
    Public Sub ShowBalloonMessage(ByVal title As String, ByVal msg As String)
        _trayNotifyIcon.ShowBalloonTip(10000, appName & " - " & title, msg, System.Windows.Forms.ToolTipIcon.Info)
    End Sub

    ''' <summary>
    ''' Gets or sets a value indicating whether the window should
    ''' show a notification icon in the system tray.
    ''' </summary>
    Public Property ShowTrayIcon() As Boolean
        Get
            Return _trayNotifyIcon.Visible
        End Get
        Set(ByVal value As Boolean)
            appName = Title
            _trayNotifyIcon.Text = appName
            _trayNotifyIcon.Visible = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the Icon used by the application NotifyIcon
    ''' </summary>
    Public Property TrayIcon() As Icon
        Get
            Return _trayNotifyIcon.Icon
        End Get
        Set(ByVal value As Icon)
            _trayNotifyIcon.Icon = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the mnu used by the application NotifyIcon
    ''' </summary>
    Public Property TrayIconMenu() As WinForms.ContextMenu
        Get
            Return _trayNotifyIcon.ContextMenu
        End Get
        Set(ByVal value As WinForms.ContextMenu)
            _trayNotifyIcon.ContextMenu = value
        End Set
    End Property
End Class
